package io.servicios;

import io.red.ConfigurableClientSocketFactory;
import io.red.ConfigurableServerSocketFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 *
 * @author Mariano Zapata
 */
public class Conexion extends Thread {
    
    private InterfazServiciosServidor serviciosServidor;
    private int id;
    private Registry servidorRMIRemoto;
    private Registry servidorRMILocal;
    private ServiciosCliente serviciosCliente;
    private ConexionListener conexionListener;
    private boolean vida;
    
    private static final String NOMBRE_SERVICIOS= "ServiciosCliente";
    private static final String SERVICIOS_SERVIDOR= "ServiciosServidor";
    
    private static final long TIEMPO_ESPERA= 5000;
    
    public Conexion() throws RemoteException
    {
        vida= true;
        serviciosCliente= new ServiciosCliente();
        serviciosServidor= null;
        servidorRMIRemoto= null;
        servidorRMILocal= null;
        conexionListener= null;
        id= -1;
    }
    
    public void conectarServicio(String ipServidor, int puertoRMIRemoto, int puertoRMILocal, InetAddress ipLocal)
            throws RemoteException, NotBoundException, UnknownHostException
    {
        ConfigurableServerSocketFactory cssf= new ConfigurableServerSocketFactory(ipLocal);
        ConfigurableClientSocketFactory ccsf= new ConfigurableClientSocketFactory();
        servidorRMILocal= LocateRegistry.createRegistry(puertoRMILocal, ccsf, cssf);
        servidorRMILocal.rebind(NOMBRE_SERVICIOS, serviciosCliente);
        servidorRMIRemoto= LocateRegistry.getRegistry(ipServidor, puertoRMIRemoto);
        serviciosServidor= (InterfazServiciosServidor) servidorRMIRemoto.lookup(SERVICIOS_SERVIDOR);
        if (ipLocal == null)
            id= serviciosServidor.conectar("0.0.0.0", puertoRMILocal);
        else
            id= serviciosServidor.conectar(ipLocal.getHostAddress(), puertoRMILocal);
        this.start();
    }
    
    public void desconectarServicio()
    {
        try {
            this.interrupt();
            if (serviciosServidor != null)
                serviciosServidor.desconectar(id);
        } catch (RemoteException ex) {}
          finally {if (serviciosCliente != null)
                       serviciosCliente.detener();}
    }
    
    public InterfazServiciosServidor getServiciosServidor() {
        return serviciosServidor;
    }
    
    public int getIdConexion() {
        return id;
    }
    
    public void agregarActualizadorListener(ActualizadorListener al) {
        serviciosCliente.agregarActualizadorListener(al);
    }
    
    public void quitarActualizadorListener() {
        serviciosCliente.quitarActualizadorListener();
    }
    
    public void agregarConexionListener(ConexionListener cl) {
        conexionListener= cl;
    }
    
    public void quitarConexionListener() {
        conexionListener= null;
    }
    
    public String getDirectorioTemp() {
        return serviciosCliente.getDirectorioTemp();
    }
    
    @Override
    @SuppressWarnings("SleepWhileHoldingLock")
    public void run()
    {
        while (vida)
        {
            try {
                Thread.sleep(TIEMPO_ESPERA);
                serviciosServidor.estaVivo();
            } catch (RemoteException ex) {vida= false;
                                          if (conexionListener != null)
                                              conexionListener.conexionPerdida();}
              catch (InterruptedException ex) {vida= false;}
        }
    }
}